package org.amse.Archiver.algorithm;
import java.io.*;

import org.amse.Archiver.algorithm.huffman.*;

public class DataDecoderStream implements IDecoder {
	private static final int STAT_LEN = 256;
	private final DataInputStream myInput;
	private DataOutputStream myOut;
	private String myName;
	private StringBuffer myPath = new StringBuffer();
	private ITree myTree;
	private int mySize;
	private int[] myStatistic  = new int[STAT_LEN];
	private File in;
	public DataDecoderStream(File input) throws IOException{
		in = input;
		myPath.append(in.getPath());
		System.out.println(myPath);
		myInput = new DataInputStream(new FileInputStream (input));		
	}
    
	public void readTechInf() throws IOException {
		myName = myInput.readUTF();
		mySize = myInput.readInt();
		for (int i = 0; i < STAT_LEN; i++) {
    		int ch;
			ch = myInput.readInt();
    		myStatistic[i] = ch;
    	}
		
	}
	public int[] getStat(){
			return myStatistic;
	}
	public void decode() throws IOException {
		readTechInf();
		myPath.delete(myPath.indexOf(in.getName()), myPath.length()).append(myName);
		myOut = new DataOutputStream(new FileOutputStream(new File(myPath.toString())));
		myTree = new HuffmanTree(myStatistic);
    	myTree.buildTree();
    	Node root = myTree.getRoot();
    	Node currentNode = root;
    	byte ch;
        int writtenNum = 0;
        while (true) {
        	try{
        	    ch = myInput.readByte();
        	 }  catch(EOFException e ){
     		    myInput.close();
     		    myOut.close();
     	    	return;
        	 }
        	    int currBit;
    		    int tmpBit;
    		    int num = 8; 
    		    for (int i = 0; i < num; i++) {
    		    	tmpBit = 1 << (7-i);
    		        currBit = ch & tmpBit;
    		        if (currentNode.getLeft() != null && currentNode.getRight() != null){
    		            if (currBit == 0) {
    		            	currentNode = currentNode.getRight();
    		            } else {
    		            	currentNode = currentNode.getLeft();
    		            }
    	            } 
    	   
    		        if(currentNode.getLeft() == null && currentNode.getRight() == null){
    	    	        int sym = currentNode.getCodeSym();
                        if(writtenNum < mySize){
   	    	                myOut.writeByte(sym);
                            writtenNum++;                             
                        }
    	    	        currentNode = root;
    	            }	
    		    }
    	      
        }
    
   }

	public String getName() {
		return myPath.toString();
	}
	
}
